package com.ksj.Service;

import com.ksj.Utils.JdbcTool.JdbcTool;
import com.ksj.Utils.MqttTool.MqttTool;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class AlarmService implements MessageListener {

    private static Logger LOG = LoggerFactory.getLogger(AlarmService.class);
    //设备类型表缓存
    private static Map<String, Map<String, Object>> deviceTableCache = new HashMap<>();

    @Override
    public void onMessage(Message message) {
        try {
            String msg = ((TextMessage) message).getText();
            handleData(msg);
        } catch (JMSException e) {
            LOG.error("JMS异常!", e);
        }
    }

    //处理数据
    public static void handleData(String data) {
        JSONObject obj = new JSONObject(data);
        /**
         3.1.2. flag=T 回复类型数据，存入数据库，修改交易表中指定交易件
         flag=A分两种情况:
         报警等级 = 0是普通交易，流程事件（例如工号改变），找到未改变前的工号，修改指定交易记录，并且插入一条新的工号改变记录。
         报警等级 > 0 时为报警事
         (1)判断报警点位类型（报警动作或复位），在数据库中做出相应的操作；
         (2)判断报警严重等级，从而做出指定通知操作。
         */
        //获取数据的phone字段并查询数据库所对应的设备类型
        String phone = obj.getString("PHONE");
        //判断缓存
        Map<String, Object> cache;
        //判断是否存在缓存 不存在缓存再去查询然后添加到缓存 存在则直接取缓存
        if (!deviceTableCache.containsKey(phone)) {
            String[] clos = {"ShebeiLeixing", "ShebeiBiao"};
            cache = JdbcTool.selectMap(clos, "shebeileixing", "phone = '" + phone + "'");
            if (cache.size() == 0) {
                LOG.error(phone + "没有配置所对应的设备类型以及设备表~!");
                return;
            }
            deviceTableCache.put(phone, cache);
        } else
            cache = deviceTableCache.get(phone);
        //获取body
        JSONObject body = obj.getJSONObject("body");
        for (String key : body.keySet()) {
            //获取body中的每一个对象
            JSONObject object = body.getJSONObject(key);
            //获取对象中的REG_EMERG
            JSONObject REG_EMERG = object.getJSONObject("REG_EMERG");
            JSONObject REG_ALARM = object.getJSONObject("REG_ALARM");
            JSONObject REG_VAL = object.getJSONObject("REG_VAL");


            //遍历REG_EMERG
            for (String emergKey : REG_EMERG.keySet()) {
                Integer alarmRank = REG_EMERG.getInt(emergKey);

                //获取点位的配置信息
                String[] cols = {"mode", "attach_point", "complete_statu", "uncomplete_statu"};
                Map<String, Object> map = JdbcTool.selectMap(cols, "transaction_point_comfig",
                        "point = '" + emergKey + "' AND device_type = '" + cache.get("ShebeiLeixing") + "'");

                if (alarmRank == 0) {/**普通流程事件*/
                    //获取指定点位对应流程处理操作
                    String info = map.get("attach_point").toString();
                    String[] keys = info.split(",");


                    try {

                        if (Integer.valueOf(map.get("mode").toString()) == 0
                                || Integer.valueOf(map.get("mode").toString()) == 2) {
                            String sql = "SELECT " + emergKey;
                            for (String subKey : keys) {
                                sql += "," + subKey;
                            }
                            sql += " FROM ? WHERE PHONE = ? AND ? != ? ORDER BY TIME DESC LIMIT 1";
                            PreparedStatement st = JdbcTool.getConn().prepareStatement(sql);
                            st.setString(1, cache.get("ShebeiBiao").toString());
                            st.setString(2, phone);
                            st.setString(3, emergKey);
                            st.setString(4, REG_VAL.getString(emergKey));
                            ResultSet set = st.executeQuery();

                            Map<String, Object> result = new HashMap<>();
                            while (set.next()) {
                                for (int i = 0; i < set.getMetaData().getColumnCount(); i++) {
                                    result.put(set.getMetaData().getColumnName(i + 1), set.getString(i + 1));
                                }
                            }
                            String upSql = "UPDATE jiaoyi SET status = ?";
                            for (int i = 0; i < keys.length; i++) {
                                upSql += ",dwName" + i + " = '" + keys[i] + "',dwVal" + i + " = '" + result.get(keys[i]) + "'";
                            }
                            upSql += " WHERE alarmName = ? AND PHONE = ? AND status = ? AND status < 9999";
                            PreparedStatement upSt = JdbcTool.getConn().prepareStatement(upSql);
                            System.out.println("sql ------------> " + upSql);
                            upSt.setString(1, map.get("complete_statu").toString());
                            upSt.setString(2, emergKey);
                            upSt.setString(3, phone);
                            upSt.setString(4, map.get("uncomplete_statu").toString());
                            if (upSt.executeUpdate() > 0) {
                                LOG.info("修改" + emergKey + "点位交易记录成功~!");
                            }
                        }

                        if (Integer.valueOf(map.get("mode").toString()) == 1
                                || Integer.valueOf(map.get("mode").toString()) == 2) {
                            String inSql = "INSERT INTO jiaoyi (phone,status,flag,alarmName,alarmVal,alarmType,alarmEmerge";
                            for (int i = 0; i < keys.length; i++) {
                                inSql += ",dwName" + i + ",dwVal" + i;
                            }
                            inSql += ") VALUES (?,?,?,?,?,?,?";
                            for (int i = 0; i < keys.length; i++) {
                                inSql += ",?,?";
                            }
                            inSql += ")";

                            PreparedStatement inSt = JdbcTool.getConn().prepareStatement(inSql);
                            inSt.setString(1, phone);
                            inSt.setString(2,  map.get("uncomplete_statu").toString());
                            inSt.setString(3, "A");
                            inSt.setString(4, emergKey);
                            inSt.setString(5, String.valueOf(REG_VAL.get(emergKey)));
                            inSt.setString(6, String.valueOf(REG_ALARM.get(emergKey)));
                            inSt.setString(7, String.valueOf(REG_EMERG.get(emergKey)));
                            for (int i = 1; i <= keys.length; i++) {
                                inSt.setString(7 + i, "");
                                inSt.setString(7 + i + 1, "");
                            }
                            if (inSt.executeUpdate() > 0) {
                                LOG.info("插入" + emergKey + "点位交易记录成功~!");
                            }
                        }
                    } catch (SQLException e) {
                        LOG.error("SQL异常！", e);
                    }


                } else if (alarmRank > 0) {
                    //报警事件
                    LOG.info("报警事件~!");
                    //将报警点位存储到jiaoyi表 调用相应的方法
                    for (String subKey : REG_ALARM.keySet()) {

                        int flags = Integer.valueOf(String.valueOf(REG_ALARM.get(subKey)));
                        Map<String, Object> reg_val = REG_VAL.toMap();
                        Map<String, Object> reg_emerge = REG_EMERG.toMap();

                        switch (flags) {
                            case 1:
                                //判断是报警复归,更改jiaoyi表。
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "0");
                                break;
                            case 2:
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "6");
                                break;
                            case 3:
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "7");
                                break;
                            case 4:
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "8");
                                break;
                            case 5:
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "9");
                                break;
                            case 10:
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "12");
                                break;
                            case 11:
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "13");
                                break;
                            case 16:
                                JdbcTool.updateBaojing(phone, String.valueOf(flags), subKey, "15");
                                break;
                            default:
                                JdbcTool.insertBaojing(phone, String.valueOf(flags), subKey, reg_val.get(subKey).toString(), reg_emerge.get(subKey).toString());
                                break;
                        }

                        //发送推送消息
                        MqttTool.sendQueueMsg("ALARM/NOTIFY", data);

                    }

                }
            }
        }
    }
}
